package cn.stylefeng.guns.modular.business.service.impl;

import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.config.redis.redis.util.Redishandler0;
import cn.stylefeng.guns.core.MessageNoticeType;
import cn.stylefeng.guns.core.MoneyLogType;
import cn.stylefeng.guns.core.RecoverConst;
import cn.stylefeng.guns.core.UserGradeLevel;
import cn.stylefeng.guns.modular.business.entity.UserGrade;
import cn.stylefeng.guns.modular.business.entity.UserProperty;
import cn.stylefeng.guns.modular.business.mapper.MoneyLogMapper;
import cn.stylefeng.guns.modular.business.mapper.UserPropertyMapper;
import cn.stylefeng.guns.modular.business.model.dto.KeyValueDTO;
import cn.stylefeng.guns.modular.business.model.params.*;
import cn.stylefeng.guns.modular.business.model.result.MoneyLogResult;
import cn.stylefeng.guns.modular.business.model.result.UserPropertyResult;
import cn.stylefeng.guns.modular.business.model.result.UserTeamResult;
import cn.stylefeng.guns.modular.business.service.MessageNoticeService;
import cn.stylefeng.guns.modular.business.service.MessageService;
import cn.stylefeng.guns.modular.business.service.UserPropertyService;
import cn.stylefeng.guns.sys.core.util.StringUtils;
import cn.stylefeng.guns.sys.modular.system.entity.User;
import cn.stylefeng.guns.sys.modular.system.service.UserService;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户属性表 服务实现类
 * </p>
 *
 * @author jwj
 * @since 2019-07-19
 */
@Service("userPropertyService")
@Slf4j
public class UserPropertyServiceImpl extends ServiceImpl<UserPropertyMapper, UserProperty> implements UserPropertyService {


    @Autowired
    private MoneyLogMapper moneyLogMapper;

    @Autowired
    private Redishandler0 redishandler0;

    @Autowired
    private MessageNoticeService messageNoticeService;

    @Autowired
    private UserService userService;

    @Autowired
    private MessageService messageService;

    @Override
    public void add(UserPropertyParam param){
        UserProperty entity = getEntity(param);
        this.save(entity);
    }

    /**
     * 获取用户等级信息
     *
     * @param userId
     * @return
     */
    @Override
    public JSONObject getPropertyByUser(Long userId) {
        UserProperty userProperty = this.getById(userId);
        if (userProperty != null) {
            JSONObject result = JSONObject.parseObject(JSONObject.toJSONString(userProperty));
            if (userProperty.getGradeLevel().equals(UserGradeLevel.first_level.getCode())) {
                result.put("gradeName", "普通会员");
            } else {
                result.put("gradeName", "VIP黄金会员");
            }
            return result;
        }
        return null;
    }
    /**
     * 获取用户等级信息
     *
     * @param userId
     * @return
     */
    @Override
    public UserProperty getPropertyByUserId(Long userId) {
        UserProperty userProperty = this.getById(userId);
        if (userProperty != null) {
            return userProperty;
        }
        return null;
    }

    @Override
    public void delete(UserPropertyParam param){
        this.removeById(getKey(param));
    }

    @Override
    public void update(UserPropertyParam param){
        UserProperty oldEntity = getOldEntity(param);
        UserProperty newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        this.updateById(newEntity);
    }

    @Override
    public UserPropertyResult findBySpec(UserPropertyParam param){
        return null;
    }

    @Override
    public List<UserPropertyResult> findListBySpec(UserPropertyParam param){
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(UserPropertyParam param){
        Page pageContext = getPageContext();
        IPage page = this.baseMapper.customPageList(pageContext, param);
        return LayuiPageFactory.createPageInfo(page);
    }


    /**
     * 获取我的推荐列表
     *
     * @param page
     * @param userTeamParam
     * @return
     */
    @Override
    public Page<UserTeamResult> getMyPushList(Page page, UserTeamParam userTeamParam) {
        /**
         * 1、先获取用户列表
         * 2、再根据id统计收益
         * 3、再根据id统计人数
         * TODO 后面改成定时任务统计保存，直接查询统计结果
         */
        if (userTeamParam.getPushType().equals(1)) {
            userTeamParam.setParentUserId(userTeamParam.getUserId());
        } else {
            userTeamParam.setParentPushUserId(userTeamParam.getUserId());
        }
        Page<UserTeamResult> pageTeam = baseMapper.getMyPushPage(page, userTeamParam);
        //处理推荐个数
        List<Long> userIds = new ArrayList<>();
        List<UserTeamResult> list = pageTeam.getRecords();
        if (list == null || list.size() == 0) {
            return pageTeam;
        }
        UserIdsParam userIdsParam = new UserIdsParam();
        for (UserTeamResult userTeamResult : list) {
            userIds.add(userTeamResult.getUserId());
        }
        if (userTeamParam.getPushType().equals(1)) {
            userIdsParam.setUserIds(userIds);
        } else {
            userIdsParam.setPushUserIds(userIds);
        }

        List<UserTeamResult> pushList = null;
        Map<Long, UserTeamResult> pushCountMap = new HashMap<>();
        if (userTeamParam.getPushType().equals(1)) {
            pushList = this.baseMapper.getZPushListByIds(userIdsParam);
        } else {
            pushList = this.baseMapper.getJPushListByIds(userIdsParam);
        }
        pushCountMap =  pushList.stream().collect(Collectors.toMap(UserTeamResult::getUserId, Function.identity()));
        for (UserTeamResult userTeamResult : list) {
            UserTeamResult mapEntity = pushCountMap.get(userTeamResult.getUserId());
            if (mapEntity != null) {
                userTeamResult.setTeamNum(mapEntity.getTeamNum());
            }
        }
        //处理推荐收益
        MoneyLogParam moneyLogParam = new MoneyLogParam();
        moneyLogParam.setComeUserIds(userIds);
        moneyLogParam.setUserId(userTeamParam.getUserId());
        if (userTeamParam.getPushType().equals(1)) {
            moneyLogParam.setType(MoneyLogType.CARD_EXTEND_Z.getCode());
        } else {
            moneyLogParam.setType(MoneyLogType.CARD_EXTEND_J.getCode());
        }
        List<MoneyLogResult> moneyList = moneyLogMapper.getZPushMoneyListByIds(moneyLogParam);
        Map<Long, MoneyLogResult> moneyMap = moneyList.stream().collect(Collectors.toMap(MoneyLogResult::getComeUserId, Function.identity()));
        for (UserTeamResult userTeamResult : list) {
            MoneyLogResult moneyLogResult = moneyMap.get(userTeamResult.getUserId());
            if (moneyLogResult != null ) {
                userTeamResult.setAmount(moneyLogResult.getAmount());
            }
        }
        return pageTeam;
    }

    private Serializable getKey(UserPropertyParam param){
        return param.getUserId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private UserProperty getOldEntity(UserPropertyParam param) {
        return this.getById(getKey(param));
    }

    private UserProperty getEntity(UserPropertyParam param) {
        UserProperty entity = new UserProperty();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }

    /**
     * //获取所有用户等级
     *
     * @param userIdList
     * @return
     */
    @Override
    public List<KeyValueDTO<Integer>> getUserGradeLevel(List<Long> userIdList) {
        return this.baseMapper.getUserGradeLevel(userIdList);
    }

    /**
     * sys工程获升级等级
     *
     * @param userId
     * @return
     */
    @Override
    public boolean sysToUpUserGrade(Long userId) {
        UserProperty userProperty = this.getById(userId);
        if (userProperty.getGradeLevel().equals(UserGradeLevel.second_level.getCode())) {
            log.info("用户：" +userId + "已经是vip，无需升级");
            return true;
        }
        String gradeStr = redishandler0.getHash(RecoverConst.USER_GRADE_REDIS_KEY, "",  UserGradeLevel.second_level.getCode() + "");
        UserGrade userGrade = null;
        if (StringUtils.isNotEmpty(gradeStr)) {
            userGrade = JSONObject.parseObject(gradeStr, UserGrade.class);
        }
        userProperty.setGradeLevel(UserGradeLevel.second_level.getCode());
        userProperty.setGradeId(userGrade.getGradeId());
        if (StringUtils.isNotEmpty(userProperty.getRelationPath())) {
            userProperty.setRelationPath(userProperty.getRelationPath().split("-")[0]);
        }
        userProperty.setRecommendLevel(RecoverConst.USER_GRADE_LEVEL_FIRST);
        this.updateById(userProperty);
        //发送消息
        User user = userService.getById(userId);
        messageNoticeService.add("升级成功通知", "你好，恭喜你成功升级VIP黄金会员，感谢您的使用", MessageNoticeType.system.getCode(), userId);
        sendSuccessMessageToUser(user.getOpenid());
        return true;
    }

    /**
     * 发送升级通知
     * @param openId
     */
    private void sendSuccessMessageToUser(String openId) {
        MessageDTO messageDTO = new MessageDTO();
        messageDTO.setUserIdList(Collections.singletonList(openId));
        messageDTO.setMessageType(MessageType.UP_GRADE);
        WxMessageDTO wxMessageDTO = new WxMessageDTO();
        wxMessageDTO.setFirst("您好，您已成功升级为VIP黄金会员");
        wxMessageDTO.setKeyword1("VIP黄金会员");
        wxMessageDTO.setKeyword2("永久有效");
        wxMessageDTO.setRemark("升级之后，您将获得更多的优惠机会。");
        messageDTO.setData(wxMessageDTO);
        messageService.sendTemplateMessage(messageDTO);
    }

}
